package cn.okcode.api.framework.js;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;

public class ClassInfoHelper {
    public List<ClassInfoBean> getClassInfo(String[] classNames) {
        List<ClassInfoBean> classInfoBeans = new ArrayList<>();
        for (String className : classNames) {
            Class<?> clazz;
            try {
                clazz = Class.forName(className);
            } catch (ClassNotFoundException e) {
                throw new RuntimeException("类" + className + "不存在", e);
            }
            if (clazz.isInterface() || !Modifier.isPublic(clazz.getModifiers())) {
                continue;
            }
            List<MethodInfo> methodInfo = new ArrayList<>();
            List<MethodInfo> staticMethodInfo = new ArrayList<>();
            List<List<String>> constructorInfo = new ArrayList<>();

            Method[] methods = clazz.getMethods();
            for (Method method : methods) {
                if (!Modifier.isPublic(method.getModifiers())) {
                    continue;
                }
                String methodName = method.getName();
                Class<?>[] parameterTypes = method.getParameterTypes();
                List<String> typeNames = new ArrayList<>(parameterTypes.length);
                for (Class<?> parameterType : parameterTypes) {
                    typeNames.add(parameterType.getName());
                }
                if (Modifier.isStatic(method.getModifiers())) {
                    staticMethodInfo.add(new MethodInfo(methodName, typeNames));
                } else {
                    methodInfo.add(new MethodInfo(methodName, typeNames));
                }
            }
            Constructor<?>[] constructors = clazz.getConstructors();
            for (Constructor<?> constructor : constructors) {
                Class<?>[] parameterTypes = constructor.getParameterTypes();
                List<String> typeNames = new ArrayList<>(parameterTypes.length);
                for (Class<?> parameterType : parameterTypes) {
                    typeNames.add(parameterType.getName());
                }
                constructorInfo.add(typeNames);
            }

            ClassInfoBean classInfoBean = new ClassInfoBean(clazz.getName(), methodInfo, staticMethodInfo, constructorInfo);
            classInfoBeans.add(classInfoBean);
        }
        return classInfoBeans;
    }
}
